package ${packageName};
import java.math.BigDecimal;

import com.gingkoo.gf4j2.framework.entity.base.RootEntity;
import com.gingkoo.gf4j2.framework.entity.base.WithDataDate;
import com.gingkoo.gf4j2.framework.entity.base.WithDataHolder;
import com.gingkoo.gf4j2.framework.entity.base.WithDataId;
import com.gingkoo.gf4j2.framework.entity.base.WithDataTracker;
import com.gingkoo.gf4j2.framework.entity.base.WithDataVersion;
import com.gingkoo.gf4j2.framework.entity.base.WithSingleKey;
import com.google.common.base.MoreObjects;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "${tableInfo.tableName?upper_case}")
public class ${tableInfo.firstUpperEntityName} extends RootEntity implements WithDataId, WithDataDate, WithSingleKey, WithDataHolder, WithDataTracker, WithDataVersion {
<#list tableFields as tableField>
    /**
    * ${tableField.columnComment!''}
    */
    <#if (tableField.fieldName)??&&(tableField.fieldName == "dataId")>
    @Id
    </#if>
    @Column(name = "${tableField.columnName!''}")
    private ${tableField.fieldType} ${tableField.fieldName};

</#list>
    private static final long serialVersionUID = 1L;
<#list tableFields as tableField>
    /**
    * 获取 ${tableField.columnComment!''}
    *
    * @return ${tableField.columnName!''} - ${tableField.columnComment!''}
    */
    public ${tableField.fieldType} get${tableField.firstUpperFieldName!''}() {
        return ${tableField.fieldName!''};
    }

    /**
    * 设置 ${tableField.columnComment!''}
    *
    * @param ${tableField.fieldName} ${tableField.columnComment!''}
    */
    public void set${tableField.firstUpperFieldName!''}(${tableField.fieldType} ${tableField.fieldName}) {
    <#if (tableField.fieldType??)&&(tableField.fieldType == "String")>
        this.${tableField.fieldName} = ${tableField.fieldName} == null ? null : ${tableField.fieldName}.trim();
    <#else>
        this.${tableField.fieldName} = ${tableField.fieldName};
    </#if>
    }
</#list>
    @Override
    public String getPrimaryKey() {
        return get(Columns.DATA_ID);
    }

    @Override
    public void setPrimaryKey(String key) {
        set(Columns.DATA_ID, key);
    }

    @Override
    public boolean contains(String column) {
        return Columns.parse(column) != null;
    }

    public String get(Columns column) {
        Object value;
        if (column == null) {
            return null;
        }
        switch (column) {
    <#list tableFields as tableField>
            case ${tableField.columnName!''}: {
            <#if (tableField.fieldType??)&&(tableField.fieldType == "String")>
                return get${tableField.firstUpperFieldName!''}();
            <#else>
                return (value = get${tableField.firstUpperFieldName!''}()) == null ? null : value.toString();
            </#if>
            }
    </#list>
            default: {
                return null;
            }
        }
    }

    @Override
    public String get(String column) {
        return get(Columns.parse(column));
    }

    @Override
    public Map<String, String> get(Map<String, String> map) {
        for (Columns c: Columns.values()) {
            map.put(c.toString(), get(c));
        }
        return map;
    }

    public ${tableInfo.firstUpperEntityName} set(Columns column, String value) {
        if (column == null){
            return this;
        }
        switch (column) {
        <#list tableFields as tableField>
            case ${tableField.columnName!''}: {
            <#if (tableField.fieldType??)&&(tableField.fieldType == "String")>
                set${tableField.firstUpperFieldName!''}(value);
            <#else>
                value = trimToNull(value);
                set${tableField.firstUpperFieldName!''}(value == null ? null : new ${tableField.fieldType!''}(value));
            </#if>
            break;
            }
        </#list>
            default: {
                break;
            }
        }
        return this;
    }

    @Override
    public ${tableInfo.firstUpperEntityName} set(String column, String value) {
        return set(Columns.parse(column), value);
    }

    @Override
    public ${tableInfo.firstUpperEntityName} set(Map<String, ?> map) {
        for (Columns c: Columns.values()) {
            if (map.containsKey(c.toString())) {
                Object v = map.get(c.toString());
                set(c, v == null ? null : v.toString());
            }
        }
        return this;
    }

    @Override
    public ${tableInfo.firstUpperEntityName} set(RootEntity table) {
        return set(table.get());
    }

    @Override
    public List<RootEntity.Columns> getColumns() {
        return Arrays.<RootEntity.Columns>asList(Columns.values());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        };
        if (o == null || getClass() != o.getClass()){
            return false;
        }
        ${tableInfo.firstUpperEntityName} that = (${tableInfo.firstUpperEntityName}) o;
        return Objects.equals(getDataId(), that.getDataId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(
            getDataId()
        );
    }
    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this).omitNullValues()
        <#list tableFields as tableField>
            .add("${tableField.fieldName!''}", get${tableField.firstUpperFieldName}())
        </#list>
            .toString();
    }
    public static ${tableInfo.firstUpperEntityName} of(Map<String, ?> map) {
        ${tableInfo.firstUpperEntityName} entity = new ${tableInfo.firstUpperEntityName}();
        return entity.set(map);
    }

    public static ${tableInfo.firstUpperEntityName} of(RootEntity object) {
        ${tableInfo.firstUpperEntityName} entity = new ${tableInfo.firstUpperEntityName}();
        return entity.set(object);
    }

    public static ${tableInfo.firstUpperEntityName} of(String dataId) {
        ${tableInfo.firstUpperEntityName} entity = new ${tableInfo.firstUpperEntityName}();
        entity.setDataId(dataId);
        return entity;
    }

    public enum Columns implements RootEntity.Columns {
<#list tableFields as tableField>
    <#if (tableField.fieldName)??&&(tableField.fieldName == "dataId")>
        ${tableField.columnName!''}("${tableField.fieldName!''}", true)<#if tableField_has_next>,<#else>;</#if>
    <#else>
        ${tableField.columnName!''}("${tableField.fieldName!''}", false)<#if tableField_has_next>,<#else>;</#if>
    </#if>
</#list>

        private final String property;

        private final boolean isKey;

        Columns(String property, boolean isKey) {
            this.property = property;
            this.isKey = isKey;
        }

        @Override
        public String getProperty() {
            return property;
        }

        @Override
        public boolean isKey() {
            return isKey;
        }

        public static Columns parse(String column) {
            return RootEntity.parse(Columns.class, column);
        }
    }
}